package com.zhiyou100.dao.impl;

import cn.hutool.core.lang.Console;
import com.zhiyou100.dao.ExamDao;
import com.zhiyou100.entity.Exam;
import org.checkerframework.checker.units.qual.C;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.transaction.Transactional;
import java.util.List;

/**
 * 测试 dao 实现类
 *
 * @author yang
 * @version 1.0.0
 * @date 2020-09-24 22:36
 */
@Repository
public class ExamDaoImpl implements ExamDao {

    private SessionFactory factory;

    @Autowired
    public void setFactory(SessionFactory factory) {
        this.factory = factory;
    }

    private Session getSession() {
        return factory.openSession();
    }

    /**
     * 插入超过 15条的数据，需要开启事务，
     * 并且进行 flush 和 close 操作
     *
     * @param o 添加的对象
     */
    @Override
    public void addOne(Exam o) {
        final Session session = getSession();
        session.beginTransaction();
        session.save(o);
        session.flush();
        session.getTransaction().commit();
        session.close();
        Console.log("Exam dao 保存了 " + o);
    }

    /**
     * 自动关流
     * <p>
     * public interface Session extends SharedSessionContract, java.io.Closeable
     * Session 实现了 Closeable 接口
     * 使用 try-with-resource 格式，会自动调用 close 方法（idea 快捷键 ctrl + alt + t , 选择  try-with-resource
     *
     * @param integer 要删除的 id
     */
    @Override
    public void deleteOne(Integer integer) {
        try (Session session = getSession()) {
            session.beginTransaction();
            // 删除方法需要传入一个实体类
            session.delete(
                    Exam.builder()
                            .id(integer)
                            .build());
            session.flush();
            session.getTransaction().commit();
        }
    }

    @Override
    public void updateOne(Exam o) {
        try (Session session = getSession()) {
            session.beginTransaction();
            session.update(o);
            session.getTransaction().commit();
        }
    }

    @Override
    public List<Exam> getAll() {
        try (Session session = getSession()) {
            return session.createCriteria(Exam.class).list();
        }
    }

    @Override
    public Exam getOne(Integer integer) {
        try (Session session = getSession()) {
            return session.get(Exam.class, integer);
        }
    }

    @Override
    public Exam selectOneByField(String field, Object value) {
        return (Exam) getSession().createCriteria(Exam.class).add(Restrictions.eq(field, value)).uniqueResult();
    }

    @Override
    public List<Exam> listOfPaginationOrderByTime(Integer startIndex, Integer pageSize) {
        try (Session session = getSession()) {
            return session.createQuery("from Exam exam order by exam.time asc")
                    .setFirstResult(startIndex)
                    .setMaxResults(pageSize).list();
        }
    }
}
